package com.mxy.myapplication.util;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;

import com.google.zxing.ResultPoint;
import com.journeyapps.barcodescanner.CameraPreview;
import com.journeyapps.barcodescanner.ViewfinderView;
import com.mxy.myapplication.R;

import java.util.ArrayList;
import java.util.List;

/**
 * 自定义扫描窗口
 */

public class MyViewFindView extends ViewfinderView {

    protected static final String TAG = ViewfinderView.class.getSimpleName();
    protected static final int[] SCANNER_ALPHA = new int[]{0, 64, 128, 192, 255, 192, 128, 64};
    protected static final long ANIMATION_DELAY = 80L;
    protected static final int CURRENT_POINT_OPACITY = 160;
    protected static final int MAX_RESULT_POINTS = 20;
    protected static final int POINT_SIZE = 6;
    protected final Paint paint = new Paint(1);
    protected Bitmap resultBitmap;
    protected final int maskColor;
    protected final int resultColor;
    protected final int laserColor;
    protected final int resultPointColor;
    protected int scannerAlpha;
    protected List<ResultPoint> possibleResultPoints;
    protected List<ResultPoint> lastPossibleResultPoints;
    protected CameraPreview cameraPreview;
    protected Rect framingRect;
    protected Rect previewFramingRect;
    protected int CORNER_WIDTH = 0;//四角边框宽度
    protected int ScreenRate = 0;//四角边框长度
    protected int slideTop = 0;//扫描线从哪开始绘制
    protected int SPEEN_DISTANCE = 2;//扫描线滚动速度
    protected boolean firstdrawscanline = true;//是否首次绘制扫描线

    public MyViewFindView(Context context, AttributeSet attrs) {
        super(context, attrs);
        Resources resources = this.getResources();
        TypedArray attributes = this.getContext().obtainStyledAttributes(attrs,
                com.google.zxing.client.android.R.styleable.zxing_finder);
        this.maskColor =
                attributes.getColor(com.google.zxing.client.android.R.styleable.zxing_finder_zxing_viewfinder_mask, resources.getColor(com.google.zxing.client.android.R.color.zxing_viewfinder_mask));
        this.resultColor =
                attributes.getColor(com.google.zxing.client.android.R.styleable.zxing_finder_zxing_result_view, resources.getColor(com.google.zxing.client.android.R.color.zxing_result_view));
        this.laserColor =
                attributes.getColor(com.google.zxing.client.android.R.styleable.zxing_finder_zxing_viewfinder_laser, resources.getColor(com.google.zxing.client.android.R.color.zxing_viewfinder_laser));
        this.resultPointColor =
                attributes.getColor(com.google.zxing.client.android.R.styleable.zxing_finder_zxing_possible_result_points, resources.getColor(com.google.zxing.client.android.R.color.zxing_possible_result_points));
        attributes.recycle();
        this.scannerAlpha = 0;
        this.possibleResultPoints = new ArrayList(5);
        this.lastPossibleResultPoints = null;
        this.SPEEN_DISTANCE = SPEEN_DISTANCE * (int) (resources.getDisplayMetrics().density);
        this.CORNER_WIDTH = (int) (resources.getDisplayMetrics().density * 4);
        this.ScreenRate = (int) (resources.getDisplayMetrics().density * 15);
    }

    public void setCameraPreview(CameraPreview view) {
        this.cameraPreview = view;
        view.addStateListener(new CameraPreview.StateListener() {
            public void previewSized() {
                MyViewFindView.this.refreshSizes();
                MyViewFindView.this.invalidate();
            }

            public void previewStarted() {
            }

            public void previewStopped() {
            }

            public void cameraError(Exception error) {
            }

            public void cameraClosed() {
            }
        });
    }

    protected void refreshSizes() {
        if (this.cameraPreview != null) {
            Rect framingRect = this.cameraPreview.getFramingRect();
            Rect previewFramingRect = this.cameraPreview.getPreviewFramingRect();
            if (framingRect != null && previewFramingRect != null) {
                this.framingRect = framingRect;
                this.previewFramingRect = previewFramingRect;
            }

        }
    }

    @SuppressLint({"DrawAllocation"})
    public void onDraw(Canvas canvas) {
        this.refreshSizes();
        if (this.framingRect != null && this.previewFramingRect != null) {
            Rect frame = this.framingRect;
            Rect previewFrame = this.previewFramingRect;
            int width = canvas.getWidth();
            int height = canvas.getHeight();
            this.paint.setColor(this.resultBitmap != null ? this.resultColor : this.maskColor);
            canvas.drawRect(0.0F, 0.0F, (float) width, (float) frame.top, this.paint);
            canvas.drawRect(0.0F, (float) frame.top, (float) frame.left,
                    (float) (frame.bottom + 1), this.paint);
            canvas.drawRect((float) (frame.right + 1), (float) frame.top, (float) width,
                    (float) (frame.bottom + 1), this.paint);
            canvas.drawRect(0.0F, (float) (frame.bottom + 1), (float) width, (float) height,
                    this.paint);
            if (this.resultBitmap != null) {
                this.paint.setAlpha(160);
                canvas.drawBitmap(this.resultBitmap, null, frame, this.paint);
            } else {
                this.paint.setColor(this.laserColor);
                this.paint.setAlpha(SCANNER_ALPHA[this.scannerAlpha]);
                this.scannerAlpha = (this.scannerAlpha + 1) % SCANNER_ALPHA.length;

                //默认效果中中间的横线
//                int middle = frame.height() / 2 + frame.top;
//                canvas.drawRect((float) (frame.left + 2), (float) (middle - 1), (float) (frame
//                .right - 1), (float) (middle + 2), this.paint);

                //噪点绘制
//                float scaleX = (float) frame.width() / (float) previewFrame.width();
//                float scaleY = (float) frame.height() / (float) previewFrame.height();
//                List currentPossible = this.possibleResultPoints;
//                List currentLast = this.lastPossibleResultPoints;
//                int frameLeft = frame.left;
//                int frameTop = frame.top;
//                if (currentPossible.isEmpty()) {
//                    this.lastPossibleResultPoints = null;
//                } else {
//                    this.possibleResultPoints = new ArrayList(5);
//                    this.lastPossibleResultPoints = currentPossible;
//                    this.paint.setAlpha(160);
//                    this.paint.setColor(this.resultPointColor);
//                    Iterator radius = currentPossible.iterator();
//
//                    while (radius.hasNext()) {
//                        ResultPoint point = (ResultPoint) radius.next();
//                        canvas.drawCircle((float) (frameLeft + (int) (point.getX() * scaleX)),
//                        (float) (frameTop + (int) (point.getY() * scaleY)), 6.0F, this.paint);
//                    }
//                }
//
//                if (currentLast != null) {
//                    this.paint.setAlpha(80);
//                    this.paint.setColor(this.resultPointColor);
//                    float radius1 = 3.0F;
//                    Iterator point2 = currentLast.iterator();
//
//                    while (point2.hasNext()) {
//                        ResultPoint point1 = (ResultPoint) point2.next();
//                        canvas.drawCircle((float) (frameLeft + (int) (point1.getX() * scaleX)),
//                        (float) (frameTop + (int) (point1.getY() * scaleY)), radius1, this.paint);
//                    }
//                }

                paint.setColor(getResources().getColor(android.R.color.holo_green_light));
                canvas.drawRect(frame.left, frame.top, frame.left + ScreenRate,
                        frame.top + CORNER_WIDTH, paint);
                canvas.drawRect(frame.left, frame.top, frame.left + CORNER_WIDTH,
                        frame.top + ScreenRate, paint);
                canvas.drawRect(frame.right - ScreenRate, frame.top, frame.right,
                        frame.top + CORNER_WIDTH, paint);
                canvas.drawRect(frame.right - CORNER_WIDTH, frame.top, frame.right,
                        frame.top + ScreenRate, paint);
                canvas.drawRect(frame.left, frame.bottom - CORNER_WIDTH, frame.left
                        + ScreenRate, frame.bottom, paint);
                canvas.drawRect(frame.left, frame.bottom - ScreenRate, frame.left
                        + CORNER_WIDTH, frame.bottom, paint);
                canvas.drawRect(frame.right - ScreenRate, frame.bottom
                        - CORNER_WIDTH, frame.right, frame.bottom, paint);
                canvas.drawRect(frame.right - CORNER_WIDTH, frame.bottom
                        - ScreenRate, frame.right, frame.bottom, paint);

                //首次绘制扫描线
                if (firstdrawscanline) {
                    firstdrawscanline = false;
                    slideTop = frame.top;
                }
                //定义好扫描线每秒移动端的像素
                slideTop += SPEEN_DISTANCE;
                //判断扫描线的长度是否大于扫描框底部，若大于则重新回到扫描框头部再进行扫描
                if (slideTop >= frame.bottom - 15) {
                    slideTop = frame.top;
                }

                //动态定义出扫描线矩形
                Rect lineRect = new Rect();
                lineRect.left = frame.left;
                lineRect.right = frame.right;
                lineRect.top = slideTop;
                lineRect.bottom = slideTop + 15;
                //绘制上去
                canvas.drawBitmap(((BitmapDrawable) (getResources().getDrawable(R.drawable.zxingscanline)))
                        .getBitmap(), null, lineRect, paint);

                //第一个参数控制刷新速度
                this.postInvalidateDelayed(20L, frame.left - 6, frame.top - 6, frame.right + 6,
                        frame.bottom + 6);
            }
        }
    }

    public void drawViewfinder() {
        Bitmap resultBitmap = this.resultBitmap;
        this.resultBitmap = null;
        if (resultBitmap != null) {
            resultBitmap.recycle();
        }

        this.invalidate();
    }

    public void drawResultBitmap(Bitmap result) {
        this.resultBitmap = result;
        this.invalidate();
    }

    public void addPossibleResultPoint(ResultPoint point) {
        List points = this.possibleResultPoints;
        points.add(point);
        int size = points.size();
        if (size > 20) {
            points.subList(0, size - 10).clear();
        }
    }
}